package com.demo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
class Student implements Comparator<Student>{

	@Override
	public int compare(Student o1, Student o2) {
		return 0;
	}
	
}
public class GenricTest {
	private Map<String,Integer> score;
	public static void main(String[] args) throws Exception {
		List<Date> list1 = Arrays.asList(new Date(),new Date());
		List<String> list2 = new ArrayList<>();
		
		GenricTest  t = new GenricTest();
		//t.print(list1);
		Student s = new Student();
		System.out.println( t.getComparableTypeType(s)  );
		System.out.println( t.getType(list2) );
	}
	public  void print(List<Date> list) throws Exception{ 
		//我想得到list的参数类型 Date.class如何实现？
		   //通过方法，可以获取方法上的参数的泛型类型
        Method applyMethod = GenricTest.class.getMethod("print", List.class);
        //泛型的参数类型(如果只有一个参数，那么就取第一个)
        Type[] types = applyMethod.getGenericParameterTypes();
        ParameterizedType pType = (ParameterizedType)types[0];
        //获取方法参数泛型类型，那么就为Date
        System.err.println(pType.getActualTypeArguments()[0]);
        //获取方法参数类型，那么就为Vector
        System.err.println(pType.getRawType());
	}
	private <T> Class<?> getType(List<T> list) {
	    Type[] types = list.getClass().getGenericInterfaces();
	    for (Type type : types) {
	        if (type instanceof ParameterizedType) {
	            ParameterizedType ptype = (ParameterizedType) type;
	            if (List.class.equals(ptype.getRawType())) {
	            	System.out.println("---------------");
	                Type cmpType = ptype.getActualTypeArguments()[0];
	                if (cmpType instanceof ParameterizedType) {
	                    return (Class<?>) ((ParameterizedType) cmpType).getRawType();
	                } else {
	                    return (Class<?>) ptype.getActualTypeArguments()[0].getClass();
	                }
	            }
	        }
	    }
	    return Object.class;
	}
	
	/**
	 * 获取可比较的元素类型
	 * @param <T>
	 */
	private <T> Class<?> getComparableTypeType(Comparator<T> comparator) {
	    Type[] types = comparator.getClass().getGenericInterfaces();
	    for (Type type : types) {
	        if (type instanceof ParameterizedType) {
	            ParameterizedType ptype = (ParameterizedType) type;
	            if (Comparator.class.equals(ptype.getRawType())) {
	                Type cmpType = ptype.getActualTypeArguments()[0];
	                if (cmpType instanceof ParameterizedType) {
	                    return (Class<?>) ((ParameterizedType) cmpType).getRawType();
	                } else {
	                    return (Class<?>) ptype.getActualTypeArguments()[0];
	                }
	            }
	        }
	    }
	    return Object.class;
	}
	private static void test1() throws NoSuchFieldException {
		Class<GenricTest> clazz = GenricTest.class;
		Field f = clazz.getDeclaredField("score");
		//直接使用getType()取出类型只对普通类型的成员变量有效
		Class<?> a = f.getType();
		//下面将看到仅输出java.util.Map
		System.out.println("score的类型是:"+a);
		//获得成员变量f的泛型类型
		Type gType = f.getGenericType();
		//如果gType类型是ParameterizedType对象
		if(gType instanceof ParameterizedType){
			//强制类型转换
			ParameterizedType pType =(ParameterizedType)gType;
			//获取原始类型
			Type rType = pType.getRawType();
			System.out.println("原始类型是："+rType);
			//取得泛型类型的泛型参数
			Type[] tArgs = pType.getActualTypeArguments();
			System.out.println("泛型信息是: ");
			System.out.println(tArgs[0].getTypeName().equals(String.class.getName()));
			for(int i=0; i<tArgs.length;i++){
				System.out.println("第" + i+ "个泛型类型是" + tArgs[i]);
			}
		}
	}

}
